//
// Created by sxt on 2023/10/18.
//

#ifndef MY_REFLECT_FIELD_H
#define MY_REFLECT_FIELD_H

#include <string>
#include <any>

namespace myreflect {

    using namespace std;

    class RawTypeDescriptorBuilder;

    /**
     * 属性
     */
    class Field {

        // 声明RawTypeDescriptorBuilder为友元 供该类访问本类的私有成员
        friend  RawTypeDescriptorBuilder;

    public:

        Field() = default;

        /**
         * 根据类的某成员变量，创建一个对应Field描述符
         * @tparam Class 对应类
         * @tparam Type 对应类中的某个属性类型
         * @param var 对应类中的某个属性的指针
         */
        template<class Class, typename Type>
        explicit Field(Type Class::*var) {
            // 定义set方法
            setter = [var](any obj, any val) {
                auto *self = any_cast<Class *>(obj);
                self->*var = any_cast<Type>(val);
            };

            // 定义get方法
            getter = [var](any obj) -> any {
                return any_cast<Class *>(obj)->*var;
            };
        }

    public:
        /**
         * 给目标对象设置值
         * @tparam Class 对象类型
         * @tparam Type 值类型
         * @param obj 对象实例
         * @param val 要设置的值
         */
        template<class Class, typename Type>
        void setValue(Class &obj, Type val) {
            setter(&obj, val);
        }

        /**
         * 从目标对象获取值
         * @tparam Class 对象类型
         * @tparam Type 值类型
         * @param obj 对象实例
         * @return 获取得到的值
         */
        template<typename Type, class Class>
        Type getValue(Class &obj) const {
            return any_cast<Type>(getter(&obj));
        }

        /**
         * 获取属性名
         * @return
         */
        [[nodiscard]] const string &getFieldName() const;

    private:
        /**
         * 属性名
         */
        string fieldName;

        /**
         * get方法
         */
        function<any(any)> getter{nullptr};

        /**
         * set方法
         */
        function<void(any, any)> setter{nullptr};
    };
}


#endif //MY_REFLECT_FIELD_H
